package com.xian.ai.code.controller;

import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import com.xian.ai.code.annotation.AuthCheck;
import com.xian.ai.code.common.BaseResponse;
import com.xian.ai.code.common.DeleteRequest;
import com.xian.ai.code.common.ResultUtils;
import com.xian.ai.code.constant.UserConstant;
import com.xian.ai.code.exception.BusinessException;
import com.xian.ai.code.exception.ErrorCode;
import com.xian.ai.code.exception.ThrowUtils;
import com.xian.ai.code.manage.CosManager;
import com.xian.ai.code.model.dto.user.*;
import com.xian.ai.code.model.entity.User;
import com.xian.ai.code.model.vo.LoginUserVO;
import com.xian.ai.code.model.vo.UserSafeVO;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import com.xian.ai.code.service.UserService;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;


import static com.xian.ai.code.utils.SafeUtitl.getEncryptPassword;


/**
 *  控制层。
 *
 * @author Zhangxn
 */
@RestController
@RequestMapping("/user")
@RequiredArgsConstructor
@Slf4j
public class UserController {


    private final UserService userService;

    @Autowired
    private CosManager cosManager;

    // 控制器方法
    @PostMapping("/upload/avatar")
    public BaseResponse<String> uploadAvatar(@RequestParam("file") MultipartFile file, HttpServletRequest request) {
        // 1. 文件验证（大小、格式等）
        if (file.isEmpty()) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "文件不能为空");
        }

        // 验证文件大小（限制为2MB）
        if (file.getSize() > 2 * 1024 * 1024) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "文件大小不能超过2MB");
        }

        // 验证文件类型（只允许图片）
        String contentType = file.getContentType();
        if (ObjectUtil.isEmpty(contentType) || !contentType.startsWith("image/")) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "只允许上传图片文件");
        }

        // 2. 获取当前登录用户
        User loginUser = userService.getLoginUser(request);

        try {
            // 3. 保存文件到临时目录
            String tempDir = System.getProperty("java.io.tmpdir");
            String originalFilename = file.getOriginalFilename();
            String fileExtension = "";
            if (originalFilename != null && originalFilename.contains(".")) {
                fileExtension = originalFilename.substring(originalFilename.lastIndexOf("."));
            }

            // 生成唯一文件名
            String uniqueFileName = UUID.randomUUID().toString().replaceAll("-", "") + fileExtension;
            Path tempFilePath = Paths.get(tempDir, uniqueFileName);
            File tempFile = tempFilePath.toFile();

            // 写入临时文件
            file.transferTo(tempFile);

            // 4. 生成COS对象键
            String cosKey = generateAvatarKey(loginUser.getId(), uniqueFileName);

            // 5. 上传到COS
            String avatarUrl = cosManager.uploadFile(cosKey, tempFile);

            // 6. 清理临时文件
            Files.deleteIfExists(tempFilePath);

            // 7. 更新用户头像URL
            if (StrUtil.isNotBlank(avatarUrl)) {
                loginUser.setUserAvatar(avatarUrl);
                //userService.updateById(loginUser);
                return ResultUtils.success(avatarUrl);
            } else {
                throw new BusinessException(ErrorCode.OPERATION_ERROR, "文件上传失败");
            }
        } catch (IOException e) {
            log.error("文件上传失败", e);
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "文件上传失败");
        }
    }

    /**
     * 生成头像在COS中的存储键
     * @param userId 用户ID
     * @param fileName 文件名
     * @return COS键
     */
    private String generateAvatarKey(Long userId, String fileName) {
        String datePath = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd"));
        return String.format("/avatars/%s/%d/%s", datePath, userId, fileName);
    }

    @PostMapping("/register")
    public BaseResponse<String> userRegister(@RequestBody UserRegisterRequest userRegisterRequest) {
        ThrowUtils.throwIf(userRegisterRequest==null,ErrorCode.PARAMS_ERROR);
        String info = userService.userRegister(userRegisterRequest);
        return ResultUtils.success(info);
    }

    @PostMapping("/login")
    public BaseResponse<LoginUserVO> userLogin(@RequestBody UserLoginRequest userLoginRequest, HttpServletRequest request) {
        ThrowUtils.throwIf(userLoginRequest==null,ErrorCode.PARAMS_ERROR);
        User loginVo = userService.userLogin(userLoginRequest, request);
        return ResultUtils.success(LoginUserVO.fromEntity(loginVo));
    }

    @PostMapping("logout")
    public BaseResponse<Boolean> userLogout(HttpServletRequest request) {
        ThrowUtils.throwIf(request==null,ErrorCode.PARAMS_ERROR);
        boolean result = userService.userLogout(request);
        return ResultUtils.success(result);
    }

    @GetMapping("get/login")
    public BaseResponse<LoginUserVO> getLoginUser(HttpServletRequest request) {
        User loginUser = userService.getLoginUser(request);
        return ResultUtils.success(LoginUserVO.fromEntity(loginUser));
    }
    /*****************************/
    /**
     * 创建用户
     */
    @PostMapping("/add")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Long> addUser(@RequestBody UserAddRequest userAddRequest) {
        ThrowUtils.throwIf(userAddRequest == null, ErrorCode.PARAMS_ERROR);
        Long infoId = userService.addUser(userAddRequest);
        return ResultUtils.success(infoId);
    }

    /**
     * 根据 id 获取用户（仅管理员）
     */
    @GetMapping("/get")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<User> getUserById(long id) {
        ThrowUtils.throwIf(id <= 0, ErrorCode.PARAMS_ERROR);
        User user = userService.getById(id);
        ThrowUtils.throwIf(user == null, ErrorCode.NOT_FOUND_ERROR);
        return ResultUtils.success(user);
    }

    /**
     * 根据 id 获取包装类
     */
    @GetMapping("/get/vo")
    public BaseResponse<UserSafeVO> getUserVOById(long id) {
        BaseResponse<User> response = getUserById(id);
        User user = response.getData();

        return ResultUtils.success(UserSafeVO.fromEntity(user));
    }

    /**
     * 删除用户
     */
    @PostMapping("/delete")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Boolean> deleteUser(@RequestBody DeleteRequest deleteRequest) {
        if (deleteRequest == null || deleteRequest.getId() <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        boolean b = userService.removeById(deleteRequest.getId());
        return ResultUtils.success(b);
    }

    /**
     * 更新用户
     */
    @PostMapping("/update")
    public BaseResponse<Boolean> updateUser(@RequestBody UserUpdateRequest userUpdateRequest, HttpServletRequest request) {
        if (userUpdateRequest == null || userUpdateRequest.getId() == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }

        // 获取当前登录用户
        User loginUser = userService.getLoginUser(request);

        // 如果不是管理员，则只能更新自己的信息
        if (!loginUser.getUserRole().equals(UserConstant.ADMIN_ROLE)) {
            if (!loginUser.getId().equals(userUpdateRequest.getId())) {
                throw new BusinessException(ErrorCode.NO_AUTH_ERROR, "不允许修改其他用户信息");
            }
        }
        if (StrUtil.isNotBlank(userUpdateRequest.getUserPassword())) {
            //密码加盐
            String encryptPassword = getEncryptPassword(userUpdateRequest.getUserPassword());
            userUpdateRequest.setUserPassword(encryptPassword);
        }
        userUpdateRequest.setUserPassword(loginUser.getUserPassword());
        userUpdateRequest.setUserRole(loginUser.getUserRole());
        Boolean result = userService.updateUser(userUpdateRequest);
        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
        return ResultUtils.success(true);
    }

    /**
     * 分页获取用户封装列表（仅管理员）
     *
     * @param userQueryRequest 查询请求参数
     */
    @PostMapping("/list/page/vo")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Page<UserSafeVO>> listUserVOByPage(@RequestBody UserQueryRequest userQueryRequest) {
        ThrowUtils.throwIf(userQueryRequest == null, ErrorCode.PARAMS_ERROR);
        Page<UserSafeVO> userPage = userService.getUserPage(userQueryRequest);
        return ResultUtils.success(userPage);
    }

}
